
#ifndef _TTG_PIPELINE_NODEINFO_
#define _TTG_PIPELINE_NODEINFO_
#include "Common/Definitions.h"

#include "Common/Strings.h"
#include "Common/Structures.h"
#include "Common/Extras.h"
#include "Runtime.Low/Threads.h"
#include "Runtime.Low/Utils.h"

namespace ttg_internal
{
	namespace pipeline
	{
		//Contains information about node (statistics for prediction, runtime information, etc)
		//
		//Difference between NodeState and NodeInfo:
		//NodeState contains current information, that is needed for pipeline work
		//and can be changed during iteration
		//NodeInfo contains statistics, that is used by external essences.
		class NodeInfo :public ttg::structures::NamedObject
		{
			private:
				//For nodes.
				ttg::utils::ParameterSet *filter;
				ttg::threads::FastCriticalSection locker;			//locker for this node information.
				ttg::utils::Parameter<double> *dif_abstract;		//difficulty of all task.
				ttg::utils::Parameter<double> *dif_time;			//time difficulty (in seconds).
				double coeff;										//dif_time / dif_abstract.
				bool is_proxy;					//[obsolete]if true, this node cannot process outer task data.
				bool is_single_threaded;							//serial or parallel?
			public:
				//Creates empty information.
				NodeInfo(const char *name, bool isSingleThreaded, bool isProxy);
				//Binds current info to owner pipeline.
				//Should be called to create proper parameters.
				void bind(ttg::utils::ParameterSet *owner);
				//Unbinds current node info.
				void unBind();
				//Returns locker, which should be used for synchronization.
				inline ttg::threads::CriticalSection &getLocker()
				{ return locker; }
				//Returns filter for this node.
				inline ttg::utils::ParameterSet *getFilter()
				{ return filter; }
				//Returns type of node.
				inline bool isProxy()
						{ return is_proxy; }
				//Returns type of node.
				inline bool isSingleThreaded()
						{ return is_single_threaded; }
				inline bool isMultiThreaded()
						{ return !isSingleThreaded(); }
				//Returns difficulty of all tasks in abstract units.
				inline ttg::utils::Parameter<double> &getAbstractDifficulty()
				{ return *dif_abstract; }
				//Returns time equivalent of abstract difficulty.
				inline ttg::utils::Parameter<double> &getTimeDifficulty()
				{ return *dif_time; }
				//Returns relation getTimeDifficulty() / getAbstractDifficulty() of previous iteration.
				inline double &getCoefficient()
						{ return coeff; }
#ifdef TTG_PL_VISUALIZER
			private:
				//Statistics.
				ttg::utils::Parameter<double> *cpu_usage;		//usage of CPU by this node (in percents).
				double frame_time;								//time of current frame.
				ttg::utils::Parameter<int> *task_count;			//count of created task.
				ttg::utils::Parameter<int> *active_task_count;	//count of active task.
				std::vector<double> thread_usage;				//usage of each thread (in percents).
				std::vector<NodeInfo *> next;					//information about input-nodes.
			public:
				//Sets frame time and normalizes cpu usage and usage per threads.
				void setTimes(double frame_time, double summed_time);
				//Returns frame time for previous iteration.
				inline double getFrameTime()
						{ return frame_time; }
				//Returns usage of CPU (in percents).
				inline ttg::utils::Parameter<double> &getCpuUsage()
				{ return *cpu_usage; }
				//Returns total count of tasks.
				inline ttg::utils::Parameter<int> &getTaskCount()
				{ return *task_count; }
				//Returns count of active (unfinished) tasks.
				inline ttg::utils::Parameter<int> &getActiveTaskCount()
				{ return *active_task_count; }
				//Returns usage of threads (in percents).
				inline std::vector<double> &getThreadUsage()
						{ return thread_usage; }
				//Returns usage of i-th thread (in percents).
				inline double &getThreadUsage(size_t i)
						{ return thread_usage[i]; }
				//Returns information about input-nodes.
				inline std::vector<NodeInfo *> &getNext()
						{ return next; }
				//Stores given set to xml ("Nodes" section will be created).
				//In case of error throws Error().
				static void store(ttg::extras::XMLTree &xml,
								  ttg::structures::Enumerator<NodeInfo *> &nodes);
				//Creates connected set according to xml ("Nodes" section is expected).
				//In case of error throws Error().
				static ttg::structures::Dictionary<NodeInfo> *create(ttg::extras::XMLTree &xml);
#endif
		};
	}
}

#endif
